Linux I/O Redirection
I/O Redirection nima va nega muhim?
I/O Redirection - bu Linux tizimida buyruqlarning kiruvchi (input) va chiquvchi (output) ma'lumotlarini boshqa joylarga yo'naltirish usuli. Bu texnika system administratorlar va DevOps mutaxassislari uchun juda muhim, chunki:
- Logging - jarayonlarning natijalarini faylga saqlash
- Automation - scriptlarda ma'lumotlarni avtomatik qayta ishlash
- Monitoring - tizim holatini kuzatish va tahlil qilish
- Error handling - xatolarni alohida boshqarish
3 ta asosiy oqim (stream)
Linux'da har bir dastur 3 ta "quvur" orqali tashqi dunyo bilan aloqa qiladi:
stdin (0) ➡️ DASTUR ➡️ stdout (1)
⬇️
stderr (2)
- stdin (0) - Kiruvchi ma'lumotlar (odatda klaviatura) 📥
- stdout (1) - Normal natijalar (odatda ekran) 📤
- stderr (2) - Xato xabarlari (odatda ekran) ⚠️
Misol orqali tushuntirish:
Sizda ls buyrug'i bor. Odatda bu buyruq fayllar ro'yxatini ekranga chiqaradi (stdout). Agar mavjud bo'lmagan papkani ko'rsatsangiz, xato xabari chiqadi (stderr). I/O redirection yordamida siz bu natijalarni ekran o'rniga faylga saqlashingiz mumkin.
Output Redirection - Natijalarni Yo'naltirish
Output redirection - bu buyruq natijalarini ekran o'rniga boshqa joylarga (fayllar, boshqa buyruqlar) yuborish usuli. Bu DevOps ishlarida har kuni ishlatiladi.
1. Stdout Redirection - Normal natijalarni yo'naltirish
Stdout - bu buyruqning oddiy, kutilgan natijasi. Masalan, ls buyrug'i fayllar ro'yxatini chiqaradi, date buyrug'i joriy sanani ko'rsatadi.
# Asosiy operatorlar
ls > fayllar.txt # Yangi fayl yaratish (eski ustiga)
date >> log.txt # Mavjud faylga qo'shish
echo "Salom" > salom.txt # Matn yozish
# Real misollar
ps aux > jarayonlar.txt # Barcha ishlab turgan jarayonlar
df -h > disk_holat.txt # Disk bo'sh joyi haqida ma'lumot
docker ps > containers.txt # Ishlab turgan containerlar
kubectl get pods > k8s-pods.txt # Kubernetes pod'lari
Muhim farq:
>- faylni to'liq qayta yozadi (eski ma'lumot yo'qoladi)>>- fayl oxiriga qo'shadi (eski ma'lumot saqlanadi)
Amaliy misol:
# Har kuni disk holatini log qilish
echo "$(date): Disk holati" >> /var/log/disk.log
df -h >> /var/log/disk.log
echo "---" >> /var/log/disk.log
2. Stderr Redirection - Xatolarni yo'naltirish
Stderr - bu xato xabarlari. Normal natijadan farqli ravishda, bu alohida oqim orqali yuboriladi. Sababi shundaki, xatolar va normal natijalar aralashmasin.
# Xatolarni yo'naltirish
ls mavjud_emas 2> xato.txt # Xatolarni faylga saqlash
find / -name "*.txt" 2> /dev/null # Xatolarni ko'rsatmaslik
cp fayl1 fayl2 2>> error.log # Xatolarni log ga qo'shish
2 raqami - bu stderr'ning file descriptor raqami. Agar raqam yozmasangiz, 1 (stdout) hisoblanadi.
Amaliy misol:
# Backup script'ida xatolarni alohida yozish
rsync -av /home/user/ /backup/ 2> backup_errors.log
if [ -s backup_errors.log ]; then
echo "Backup'da xatolar bor!" | mail admin@company.com
fi
3. Stdout va Stderr ni birga boshqarish
Ko'pincha normal natija ham, xatolar ham kerak bo'ladi. Bularni birga yoki alohida yo'naltirish mumkin.
# Klassik usul - ikkalasini bitta faylga
command > natija.txt 2>&1 # Avval stdout, keyin stderr yo'naltirish
# Bash'da qisqa usul
command &> natija.txt # Bir xil natija, qisqa yozuv
# Alohida fayllar
command > natija.txt 2> xato.txt # Har birini o'z fayliga
# Hech nima ko'rsatmaslik (silent execution)
command > /dev/null 2>&1 # Barcha outputni "yutish"
2>&1 ma'nosi:
2>- stderr'ni yo'naltir&1- stdout'ga yo'naltir (1-raqamli file descriptor)- Natijada stderr ham stdout bilan bir joyga boradi
Amaliy misol:
# Deploy script'i - barcha natijalarni log'ga yozish
./deploy.sh > deploy.log 2>&1
if [ $? -eq 0 ]; then
echo "Deploy muvaffaqiyatli"
else
echo "Deploy'da muammo bor, log'ni tekshiring: deploy.log"
fi
Input Redirection - Ma'lumot Kiritish
Input redirection - bu buyruqqa ma'lumotni klaviatura o'rniga boshqa manbalardan (fayllar, scriptlar) berish usuli.
1. Fayldan Input olish
Stdin - bu buyruqqa beriladigan ma'lumot. Odatda klaviaturadan keladi, lekin fayldan ham olish mumkin.
# Fayldan ma'lumot o'qish
sort < ismlar.txt # Fayldagi ismlarni alifbo bo'yicha tartibga solish
wc -l < fayl.txt # Fayldagi qatorlar sonini hisoblash
mail user@example.com < xabar.txt # Fayldagi matnni email yuborish
# Database bilan ishlash
mysql -u root -p mydb < backup.sql # SQL faylni database'ga import qilish
psql -d mydb -f schema.sql < data.sql # PostgreSQL uchun
< belgisi - fayldan ma'lumot o'qish uchun. Bu faylning mazmunini buyruqqa input sifatida beradi.
2. Here Documents - Ko'p qatorli matn kiritish
Here Document - bu script ichida bevosita ko'p qatorli matn yozish usuli. Alohida fayl yaratmasdan turib, katta matnlarni buyruqlarga berish uchun ishlatiladi.
# Nginx konfiguratsiya yaratish
cat << EOF > /etc/nginx/sites-available/mysite
server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
try_files \$uri \$uri/ =404;
}
location /api {
proxy_pass http://localhost:3000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
}
}
EOF
# Docker Compose fayl yaratish
cat << EOF > docker-compose.yml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
EOF
# Database operatsiyalari
mysql -u root -p << EOF
CREATE DATABASE IF NOT EXISTS myapp;
USE myapp;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO users (name, email) VALUES
('John Doe', 'john@example.com'),
('Jane Smith', 'jane@example.com');
SHOW TABLES;
SELECT * FROM users;
EOF
EOF nima?
- EOF - "End Of File" ning qisqartmasi
- Bu Here Document'ning oxirini bildiradi
- EOF o'rniga istalgan so'z ishlatiladi (END, FINISH, DONE)
- Muhimi - boshlash va tugash so'zlari bir xil bo'lsin
O'zgaruvchilar bilan ishlash:
USER_NAME="admin"
PASSWORD="secret123"
DB_NAME="production"
cat << EOF > database_config.ini
[database]
host=localhost
port=3306
username=$USER_NAME
password=$PASSWORD
database=$DB_NAME
charset=utf8mb4
[logging]
level=INFO
file=/var/log/app.log
EOF
3. Here Strings - Bitta qator input
Here String - bu bitta qatorli matnni buyruqga tez berish uchun qisqa yo'l.
# JSON ma'lumotlarni qayta ishlash
jq '.' <<< '{"name": "John", "age": 30, "city": "Tashkent"}'
jq '.name' <<< '{"name": "John", "age": 30}'
# Base64 kodlash/dekodlash
echo "Hello World" | base64 # kodlash
base64 -d <<< "SGVsbG8gV29ybGQ=" # dekodlash
# String operatsiyalari
grep -i "tashkent" <<< "Men Tashkentda yashayman"
sed 's/old/new/' <<< "old text here"
# O'zgaruvchi bilan ishlash
MESSAGE="DevOps is awesome!"
grep "DevOps" <<< "$MESSAGE"
wc -w <<< "$MESSAGE" # so'zlar sonini hisoblash
<<< ma'nosi:
- O'ng tarafdagi matnni buyruqga input sifatida ber
- Here Document'dan farqli ravishda, faqat bitta qator uchun
- O'zgaruvchilar kengaytiriladi ($VAR ishlatiladi)
Advanced Techniques - Mukammal Texnikalar
1. File Descriptors - Fayl Identifikatorlari
File Descriptor (FD) - bu ochiq fayllar uchun raqamli identifikator. Standart 0,1,2 dan tashqari, qo'shimcha descriptor'lar yaratib, murakkab operatsiyalar bajarish mumkin.
# Custom file descriptor yaratish
exec 3> natija.txt # FD 3 ni faylga bog'lash
echo "Test ma'lumot" >&3 # FD 3 ga yozish
ls -la >&3 # FD 3 ga list natijasini yozish
date >&3 # FD 3 ga joriy sanani yozish
exec 3>&- # FD 3 ni yopish
# Multiple file descriptors
exec 3> success.log # Muvaffaqiyatli operatsiyalar
exec 4> error.log # Xatolar
exec 5> debug.log # Debug ma'lumotlari
echo "Jarayon boshlandi" >&3
echo "Debug: parametrlar tekshirildi" >&5
# Barcha FD larni yopish
exec 3>&- 4>&- 5>&-
Stdout Backup va Restore:
# Stdout ni vaqtincha saqlash va o'zgartirish
exec 4>&1 # Joriy stdout ni FD 4 ga saqlash
exec 1> temp.log # Stdout ni faylga yo'naltirish
echo "Bu temp.log ga yoziladi"
ls -la # Bu ham temp.log ga yoziladi
exec 1>&4 # Stdout ni tiklash (ekranga qaytarish)
exec 4>&- # Backup FD ni yopish
echo "Bu yana ekranga chiqadi"
Nima uchun kerak? Script ichida vaqtincha output'ni boshqarish, log fayllariga alohida ma'lumotlar yozish uchun juda foydali.
2. Process Substitution - Jarayon O'rniga Qo'yish
Process Substitution - bu buyruq natijasini vaqtinchalik fayl sifatida ishlatish usuli. Bu juda kuchli texnika, chunki haqiqiy fayl yaratmasdan turib buyruq natijalarini boshqa buyruqlarga berish mumkin.
# Ikki katalogni taqqoslash
diff <(ls /home/user1) <(ls /home/user2)
# Tartiblangan fayllarni taqqoslash
comm <(sort file1.txt) <(sort file2.txt)
# Ikkita server'dagi jarayonlarni taqqoslash
diff <(ssh server1 'ps aux | sort') <(ssh server2 'ps aux | sort')
# DevOps misollar
diff <(kubectl get pods -o name) <(cat expected-pods.txt)
diff <(docker ps --format "{{.Names}}") <(cat running-containers.txt)
# Database taqqoslash
diff <(mysql -e "SHOW DATABASES;" db1) <(mysql -e "SHOW DATABASES;" db2)
# Log file'larni taqqoslash
diff <(grep ERROR /var/log/app1.log) <(grep ERROR /var/log/app2.log)
<() qanday ishlaydi:
- Qavs ichidagi buyruq bajariladi
- Natija vaqtinchalik fayl sifatida taqdim etiladi
- Asosiy buyruq bu faylni o'qiydi
- Fayl avtomatik o'chiriladi
Afzalliklari:
- Haqiqiy vaqtinchalik fayl yaratmaslik
- Xotira tejash
- Jarayonlar parallel ishlaydi (tezroq)
3. Named Pipes (FIFO) - Nomlangan Quvurlar
Named Pipe - bu maxsus fayl turi bo'lib, bir jarayondan ikkinchisiga real vaqtda ma'lumot uzatish uchun ishlatiladi. Oddiy fayldan farqli ravishda, ma'lumotni saqlamas, faqat uzatadi.
# Named pipe yaratish
mkfifo /tmp/data_pipe
mkfifo /tmp/log_pipe
# Producer (Terminal 1) - ma'lumot yuboruvchi
echo "Real-time ma'lumot" > /tmp/data_pipe
date > /tmp/data_pipe
# Consumer (Terminal 2) - ma'lumot qabul qiluvchi
cat < /tmp/data_pipe
# Real-time log monitoring
mkfifo /tmp/error_pipe
# Log'dan xatolarni ajratish va pipe'ga yuborish
tail -f /var/log/app.log | grep ERROR > /tmp/error_pipe &
# Xatolarni real vaqtda qayta ishlash
while read line; do
echo "ALERT: $line"
echo "Xato vaqti: $(date)" | mail admin@company.com
done < /tmp/error_pipe
Named pipe'lar bilan complex workflow:
# Microservice'lar orasida aloqa
mkfifo /tmp/order_pipe
mkfifo /tmp/payment_pipe
mkfifo /tmp/notification_pipe
# Order service
while true; do
read order < /tmp/order_pipe
# Process order
echo "order_$order processed" > /tmp/payment_pipe
done &
# Payment service
while true; do
read payment < /tmp/payment_pipe
# Process payment
echo "payment for $payment completed" > /tmp/notification_pipe
done &
# Notification service
while true; do
read notification < /tmp/notification_pipe
echo "Notification sent: $notification"
done &
Ishlatish joylari:
- Real-time data processing
- Microservice'lar orasida aloqa
- Log monitoring va alerting
- Stream processing